package com.ocom.exposeapi.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ocom.common.HttpUtils;
import com.ocom.common.constant.ExposeApiUrl;
import com.ocom.common.entity.card.EntityXfRecordProcess;
import com.ocom.common.entity.human.EntityPersonnelInfo;
import com.ocom.common.enums.ResultEnum;
import com.ocom.common.request.company.GetComRequestRequest;
import com.ocom.common.request.payhandle.ConsumeRecordRequest;
import com.ocom.common.request.payhandle.GetRecordByOrderNoRequest;
import com.ocom.common.resp.Result;
import com.ocom.common.response.GetComRequestResponse;
import com.ocom.common.utils.ResultUtil;
import com.ocom.common.vo.human.UserInfoVo;
import com.ocom.exposeapi.feign.CompanyClientService;
import com.ocom.exposeapi.feign.HumanFeignService;
import com.ocom.exposeapi.feign.PayConfigClientService;
import com.ocom.exposeapi.feign.PayHandleClientService;
import com.ocom.exposeapi.vo.kcmzct.KCResult;
import com.ocom.redis.util.RedisUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.client.methods.HttpPost;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.util.*;

@Slf4j
@RestController
public class KcmzctController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    private CompanyClientService companyClientService;
    @Autowired
    private HumanFeignService humanFeignService;
    @Autowired
    private PayConfigClientService payConfigClientService;
    @Autowired
    private PayHandleClientService payHandleClientService;
    @Resource
    private RedisUtil redisUtil;

    static final String DOCK_CODE = "kcmzct";
    static final String SERVER_CODE = "kcmzct#ocom";
    static final String TOKEN_DOCK_API_CODE = "kcmzct#getToken";
    static final String CONSUME_RECORD_DOCK_API_CODE = "kcmzct#consumeRecord";
    static final String REDIS_TOKEN_KEY = "token/kcmzct/ocom:";

    //    @PostMapping(ExposeApiUrl.URL_ExposeApi_kcmzctGetToken)
    public Result getToken(Long comId) {
        logger.info("进入getToken接口---------------");

        Result response = ResultUtil.success();
        try {

            String getComRequestKey = "getComRequest:" + TOKEN_DOCK_API_CODE + ":" + comId;
            Object o = redisUtil.get(getComRequestKey);
            GetComRequestResponse getComRequestResponse = null;
            if (null == o) {
                GetComRequestRequest getComRequestRequest = new GetComRequestRequest();
                getComRequestRequest.setComId(comId);
                getComRequestRequest.setDockCode(DOCK_CODE);
                getComRequestRequest.setDockApiCode(TOKEN_DOCK_API_CODE);
                logger.info("getComRequest---------------:" + getComRequestRequest.toString());

                Result getComRequestResult = companyClientService.getComRequest(getComRequestRequest);
                logger.info("getComRequest结果---------------:" + getComRequestResult.toString());
                if (200 == getComRequestResult.getCode() && null != getComRequestResult.getData()) {
                    getComRequestResponse = JSON.parseObject(JSON.toJSONString(getComRequestResult.getData()), GetComRequestResponse.class);
                    redisUtil.set(getComRequestKey, JSON.toJSONString(getComRequestResponse), 60l);
                }
            } else {
                getComRequestResponse = JSON.parseObject(JSON.parse(JSON.toJSONString(o)).toString(), GetComRequestResponse.class);
            }
            if (null != getComRequestResponse) {
                Map<String, Object> reqMap = new HashMap<>();
                reqMap.put("clientId", getComRequestResponse.getSvrAppid());
                reqMap.put("clientSecret", getComRequestResponse.getMd5key());

                logger.info("----------------------kcmzctGetTokenReqMap参数" + reqMap.toString());

                String json = HttpUtils.postsJson(getComRequestResponse.getRequestUrl(), reqMap);
                log.info("----------------------json：" + json);
                KCResult result = JSON.parseObject(json, KCResult.class);
                if (10000 == result.getCode()) {
                    logger.info("----------------------kcmzctGetToken成功");
                    JSONObject jsonObject = JSON.parseObject(JSON.parse(JSON.toJSONString(result.getData())).toString());
                    String accessToken = jsonObject.getString("access_token");

                    logger.info("----------------------kcmzctToken:" + accessToken);

                    Boolean RedisResult = redisUtil.set(REDIS_TOKEN_KEY + comId, accessToken, 60 * 60 * 20L);
                    logger.info("----------------------RedisResult:" + RedisResult);
                    response.setData(accessToken);
                } else {
                    logger.info("----------------------获取token失败:" + result.getCode() + ":" + result.getMessage());
                    response = ResultUtil.error(ResultEnum.Err_3014);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("----------------------获取token异常:" + e.getMessage());
            response = ResultUtil.error(ResultEnum.Err_900);
        }
        return response;
    }


    @PostMapping(ExposeApiUrl.URL_ExposeApi_kcmzctConsumeRecord)
    public Result consumeRecord(@RequestParam Long comId, @RequestParam String tradeNo) {
        logger.info("进入订单上报接口---------------");

        Result response = ResultUtil.success();
        try {

            GetRecordByOrderNoRequest getRecordByOrderNoRequest = new GetRecordByOrderNoRequest();
            getRecordByOrderNoRequest.setCompanyId(comId);
            getRecordByOrderNoRequest.setPId(null);
            getRecordByOrderNoRequest.setOrderNo(tradeNo);
            Result getRecordByOrdernoResult = payHandleClientService.getRecordByOrderno(getRecordByOrderNoRequest);
            if (200 == getRecordByOrdernoResult.getCode() && null != getRecordByOrdernoResult.getData()) {
                EntityXfRecordProcess xfRecordProcesses = JSON.parseObject(JSON.toJSONString(getRecordByOrdernoResult.getData()), EntityXfRecordProcess.class);

                String lockKey = "consumeRecord:" + xfRecordProcesses.getOrderNo();

                if (null != xfRecordProcesses && -1 != xfRecordProcesses.getPayState() && 0 == xfRecordProcesses.getSendState() && redisUtil.lock(lockKey, 60 * 60)) {
                    String getComRequestKey = "getComRequest:" + CONSUME_RECORD_DOCK_API_CODE + ":" + comId;
                    Object o = redisUtil.get(getComRequestKey);
                    GetComRequestResponse getComRequestResponse = null;
                    if (null == o) {
                        GetComRequestRequest getComRequestRequest = new GetComRequestRequest();
                        getComRequestRequest.setComId(comId);
                        getComRequestRequest.setDockCode(DOCK_CODE);
                        getComRequestRequest.setDockApiCode(CONSUME_RECORD_DOCK_API_CODE);
                        logger.info("getComRequest---------------:" + getComRequestRequest.toString());

                        Result getComRequestResult = companyClientService.getComRequest(getComRequestRequest);
                        logger.info("getComRequest结果---------------:" + getComRequestResult.toString());
                        if (200 == getComRequestResult.getCode() && null != getComRequestResult.getData()) {
                            getComRequestResponse = JSON.parseObject(JSON.toJSONString(getComRequestResult.getData()), GetComRequestResponse.class);
                            redisUtil.set(getComRequestKey, JSON.toJSONString(getComRequestResponse), 4 * 60 * 60l);
                        }
                    } else {

                        getComRequestResponse = JSON.parseObject(JSON.parse(JSON.toJSONString(o)).toString(), GetComRequestResponse.class);
                    }

                    if (null != getComRequestResponse && StringUtils.isNotBlank(getComRequestResponse.getRequestUrl())) {
                        Map<String, Object> reqMap = new HashMap<>();

                        reqMap.put("insId", getComRequestResponse.getComAppid());
                        reqMap.put("orderNo", xfRecordProcesses.getOrderNo());
                        reqMap.put("customerId", xfRecordProcesses.getPId().toString());
                        reqMap.put("customerName", xfRecordProcesses.getPName());

                        UserInfoVo userInfoVo = new UserInfoVo();
                        userInfoVo.setPId(xfRecordProcesses.getPId().intValue());
                        userInfoVo.setComId(xfRecordProcesses.getComId());
                        userInfoVo.setOnlyOne(true);
                        Result getPersonInfo = humanFeignService.PersonnelGetPersonInfo(userInfoVo);
                        if (200 == getPersonInfo.getCode() && null != getPersonInfo.getData()) {
                            EntityPersonnelInfo entityPersonnelInfo = JSON.parseObject(JSON.toJSONString(getPersonInfo.getData()), EntityPersonnelInfo.class);
                            if (null != entityPersonnelInfo) {
                                reqMap.put("customerPhone", StringUtils.isNotBlank(entityPersonnelInfo.getPPhone()) ? entityPersonnelInfo.getPPhone() : "00000000000");
                                reqMap.put("customerAddress", StringUtils.isNotBlank(entityPersonnelInfo.getPAddress()) ? entityPersonnelInfo.getPAddress() : "无");
                                reqMap.put("idcardNum", StringUtils.isNotBlank(entityPersonnelInfo.getPIdentity()) ? entityPersonnelInfo.getPIdentity() : "0");
                            }
                        }
//                        reqMap.put("delivery_name", "");
//                        reqMap.put("delivery_card", "");
//                        reqMap.put("delivery_phone", "");
                        reqMap.put("mealType", 1);
                        reqMap.put("mealDaily", StringUtils.isNotBlank(xfRecordProcesses.getMealNo()) ? Integer.parseInt(xfRecordProcesses.getMealNo()) : 1);
                        reqMap.put("dataSource", 6);
                        reqMap.put("payType", 99);
                        reqMap.put("totalFee", xfRecordProcesses.getConsMoney());
                        reqMap.put("realFee", xfRecordProcesses.getRealMoney());
                        reqMap.put("payTime", xfRecordProcesses.getPayTime().getTime());
                        reqMap.put("payStatus", xfRecordProcesses.getPayState() == 1 ? 1 : 0);
                        reqMap.put("itemCount", 1);
                        reqMap.put("cardNo", xfRecordProcesses.getCardNo());
//                        reqMap.put("cardType", "");
//                        reqMap.put("orderItems", "");

                        logger.info("----------------------订单上报参数" + reqMap.toString());
                        HttpPost post = new HttpPost(getComRequestResponse.getRequestUrl());

                        Object tokenObj = redisUtil.get(REDIS_TOKEN_KEY + comId);
                        String token = "";
                        if (null == tokenObj) {
                            logger.info("----------------------token为空");
                            Result tokenResult = getToken(comId);
                            if (200 == tokenResult.getCode() || null != tokenResult.getData()) {
                                logger.info("----------------------订单上报重新获取token成功：" + tokenResult.getData());
                                token = tokenResult.getData().toString();
                            } else {
                                logger.info("----------------------订单上报重新获取token失败：" + tokenResult.getMsg());
                            }
                        } else {
                            logger.info("----------------------订单上报获取token成功：" + tokenObj);
                            token = tokenObj.toString();
                        }

                        if (StringUtils.isNotBlank(token)) {
                            post.addHeader("Authorization", "Bearer " + token);
                            post.addHeader("Content-Type", "application/json;charset=utf-8");

                            String json = HttpUtils.postsJson(post, reqMap);

                            log.info("----------------------json：" + json);
                            KCResult result = JSON.parseObject(json, KCResult.class);
                            if (10000 == result.getCode()) {
                                logger.info("----------------------订单上报成功:{}",xfRecordProcesses.getOrderNo());
                                payHandleClientService.sendByOrderno(xfRecordProcesses);
                            } else if (20003 == result.getCode() || 20004 == result.getCode()) {
                                logger.info("----------------------订单上报失败,token无效:" + result.getCode() + ":" + result.getMessage() + ": 订单：" + xfRecordProcesses.getOrderNo());
                                redisUtil.del(REDIS_TOKEN_KEY);
                                response = ResultUtil.error(ResultEnum.Err_3014);
                            } else {
                                logger.info("----------------------订单上报失败:" + result.getCode() + ":" + result.getMessage() + ": 订单：" + xfRecordProcesses.getOrderNo());
                                response = ResultUtil.error(ResultEnum.Err_3014);
                            }
                        }

                    }
                    redisUtil.del(RedisUtil.LOCK_PREFIX + lockKey);
                } else {
                    logger.info("----------------------订单上报失败:订单加锁失败或已上报");

                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.info("----------------------订单上报异常:" + e.getMessage() + " 订单：" + tradeNo);
            response = ResultUtil.error(ResultEnum.Err_900);
        }
        return response;
    }


}
